package drds.configuration.db.datasource;

import drds.configuration.configuration.ConfigUtil;
import drds.tools.$;
import org.apache.commons.dbcp.BasicDataSourceFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.sql.DataSource;
import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;

public class DataSourceBuilder {
    public static final Logger log = LoggerFactory.getLogger(DataSourceBuilder.class);


    public static void buildDataSourceIdToDataSourceConfigMap() throws Exception {
        Map<String, DataSourceConfig> dataSourceIdToDataSourceConfigMap = getDataSourceIdToDataSourceConfigMap();
        /**
         * 根据配置信息构建数据源
         */
        if (dataSourceIdToDataSourceConfigMap.size() == 0) {
            throw new RuntimeException("请配置数据源");
        }
        for (Entry<String, DataSourceConfig> entry : dataSourceIdToDataSourceConfigMap.entrySet()) {
            //
            DataSourceContext dataSourceContext = new DataSourceContext();
            dataSourceContext.setDataSourceId(entry.getKey());
            //
            DataSourceConfig dataSourceConfig = entry.getValue();
            Properties properties = dataSourceConfig.getProperties();
            DataSource dataSource = BasicDataSourceFactory.createDataSource(properties);
            dataSourceContext.setDataSource(dataSource);
            //

            //
            dataSourceContext.setDataSourceConfig(dataSourceConfig);
            DataSourceIdToDataSourceConfigMapContext.put(entry.getKey(), dataSourceContext);
        }
    }

    private static Map<String, DataSourceConfig> getDataSourceIdToDataSourceConfigMap() {
        try {
            // 加载MySql的驱动类
            Class.forName("org.mariadb.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            log.error("找不到驱动程序类 ，加载驱动失败！", $.printStackTraceToString(e));
            throw new RuntimeException(e);
        }
        Map<String, DataSourceConfig> dataSourceIdToDataSourceConfigMap = new HashMap<String, DataSourceConfig>();
        // /db/
        String dataSourceConfigInfoFolderPath = ConfigUtil.getConfigPath() + ConfigUtil.separator() + "db";
        log.info("数据库配置保存目录:" + dataSourceConfigInfoFolderPath);
        ///E:/apache-tomcat-7.0.61/webapps/drds_config_web_war/WEB-INF/classes/common/develop/db
        //groupDataSourceConfigInfoFolderPath="E:\\apache-tomcat-7.0.61\\webapps\\drds_config_web_war\\WEB-INF\\classes\\configuration\\develop\\db";

        //now /E:/apache-tomcat-7.0.61/webapps/drds_config_web_war/WEB-INF/classes/common/develop/db
        File dataSourceConfigInfoFolderFile = new File(dataSourceConfigInfoFolderPath);
        File[] dataBaseConfigInfoFolderFiles = dataSourceConfigInfoFolderFile.listFiles();
        if (!(dataBaseConfigInfoFolderFiles != null && dataBaseConfigInfoFolderFiles.length > 0)) {
            log.error("数据库配置保存目录下面没有配置文件");
        } else {
            // eg /db/drds_1
            for (File dataBaseConfigInfoFolderFile : dataBaseConfigInfoFolderFiles) {
                if (!dataBaseConfigInfoFolderFile.getName().startsWith("drds")) {
                    continue;
                }
                //
                File[] dataBaseConfigInfoFiles = dataBaseConfigInfoFolderFile.listFiles();
                if (dataBaseConfigInfoFiles.length > 0) {
                    log.info("组数据库配置保存目录:" + dataBaseConfigInfoFolderFile.getAbsolutePath());
                    //
                    DataSourceConfig dataSourceConfig = new DataSourceConfig();
                    // eg /db/drds_1/1.properties
                    for (File dataBaseConfigInfoFile : dataBaseConfigInfoFiles) {
                        //
                        if (dataBaseConfigInfoFile.getName().equals("datasource.properties")) {
                            log.info("---数据库配置保存目录:" + dataBaseConfigInfoFile.getAbsolutePath());
                            // 读取配置信息
                            Properties properties = ConfigUtil.load(dataBaseConfigInfoFile);
                            /**
                             * 测试数据库连接是否OK
                             */
                            Connection connection = null;
                            try {
                                String url = properties.getProperty("url");
                                String username = properties.getProperty("username");
                                String password = properties.getProperty("password");
                                connection = DriverManager.getConnection(url, username, password);
                                connection.createStatement().execute("select 1");
                            } catch (Throwable e) {
                                log.error("获取数据库连接失败", $.printStackTraceToString(e));
                                throw new RuntimeException("获取连接失败:" + dataBaseConfigInfoFile.getAbsolutePath());
                            } finally {
                                if (connection != null) {
                                    try {
                                        connection.close();
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                    }
                                }
                            }
                            dataSourceConfig.setProperties(properties);
                        }
                        // for end
                    }
                    // 必须含有一个数据源,因为要从里面获取表结构
                    if (dataSourceConfig.getProperties() == null) {
                        throw new RuntimeException("需要设置一个数据源");
                    }
                    // 不要再含有drds_了, 因为会被过滤掉
                    String dataSourceId = dataBaseConfigInfoFolderFile.getName();
                    if (dataSourceIdToDataSourceConfigMap.containsKey(dataSourceId)) {
                        throw new RuntimeException("groupDataSourceId重复:" + dataSourceId);
                    }
                    dataSourceIdToDataSourceConfigMap.put(dataSourceId, dataSourceConfig);

                }

            }
        }
        return dataSourceIdToDataSourceConfigMap;
    }
}
